package com.example.chartgpt.service;

import com.example.chartgpt.model.Messages;
import com.example.chartgpt.model.Request;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


@Service
public class OpenAiService {

    @Autowired
    private ReplyContentImp replyContentImp;
    //创建一个空的消息列表，用于存储对话历史（全局变量）
    List<Messages> messagesList = new ArrayList<>();

    public String OpenAiQuestion(String requestBody) throws Exception {

        //国内访问需要做代理，国外服务器不需要
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
        SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
        simpleClientHttpRequestFactory.setProxy(proxy);

        //要调用GPT接口发送请求，您可以使用Spring框架提供的RestTemplate类来进行操作
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setRequestFactory(simpleClientHttpRequestFactory);

        //设置请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Content-Type", "application/json");
        httpHeaders.set("Authorization", "Bearer 想看我的key嘛？做梦去吧！");


        //设置请求体(request)
        Messages messages = replyContentImp.addMessageToConversationHistory("user", requestBody);

        // 仅保留最近6条对话记录，移除旧的对话消息,避免超过ChatGPT模型的最大上下文长度。
        //据说：每次要把历史对话记录传过去，会导致后续单次请求和响应消耗的token数量越来越多，超过ChatGPT模型支持的最大上下文长度，ChatGPT就无法继续往下处理了。比如gpt-3.5-turbo支持的最大上下文长度是4097个token，如果单次请求和响应里包含的token数量超过这个数，ChatGPT就会返回如下错误：
        //This model's maximum context length is 4097 tokens. However, you requested 4103 tokens (2066 in the messages, 2037 in the completion). Please reduce the length of the messages or completion.
        if (messagesList.size() > 6) {
            messagesList = messagesList.subList(messagesList.size() - 6, messagesList.size());
        }

        // 添加到对话历史中
        messagesList.add(messages);


        //Test
        System.out.println(messagesList.toString());

        Request request = new Request();
        request.setModel("gpt-3.5-turbo");
        request.setMax_tokens(100);
//设置响应长度max_token
//        request.setMax_tokens(150);
        request.setMessages(messagesList);


// 创建 ObjectMapper 对象
        ObjectMapper objectMapper = new ObjectMapper();
// 将对象转换为 JSON 字符串
        String requestBodyJson = objectMapper.writeValueAsString(request);


        //构造HttpEntity对象
        HttpEntity<String> httpEntity = new HttpEntity<>(requestBodyJson, httpHeaders);
        //调用api接口发送请求
        String url = "https://api.openai.com/v1/chat/completions";
        //url:请求的url； HttpMethod.POST：请求方式； httpEntity：请求体； String.class：返回的数据类型
        //响应并处理
        ResponseEntity<String> request1 = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);


        //判断请求是否成功
        if (request1.getStatusCode().is2xxSuccessful()) {
            String responseBody = request1.getBody();
            System.out.println(responseBody);
            //把回答也存上去
            String s = replyContentImp.extractLastReplyContent(responseBody);
            Messages messages1 = replyContentImp.addMessageToConversationHistory("assistant", s);
            messagesList.add(messages1);

            return responseBody;
        }
        return "failed" + request1.getStatusCodeValue();
    }


}
